﻿using AutoMapper;
using Hsp.WebNovels.Common.Utility;
using Hsp.WebNovels.Model.Dtos;
using Hsp.WebNovels.Model.Models;
using Hsp.WebNovels.Web.Models;
using Hsp.WebNovels.Web.Utilities;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections;
using System.Web;

namespace Hsp.WebNovels.Web.Controllers
{
    public class NovelController : BaseController
    {
        #region 控制器初始化

        private readonly IMapper _mapper;
        private readonly ILogger<NovelController> _logger;
        private readonly NovelsContext _context;
        private readonly IWebHostEnvironment _env;

        /// <summary>
        /// 小说控制器构造函数
        /// </summary>
        public NovelController(ILogger<NovelController> logger, NovelsContext context, IMapper mapper, IWebHostEnvironment env) : base(logger, context, mapper)
        {
            this._logger = logger;
            this._mapper = mapper;
            this._context = context;
            this._env = env;
        }

        #endregion

        /// <summary>
        /// 小说管理
        /// </summary>
        /// <param name="webId">小说ID</param>
        /// <param name="webName">小说名称</param>
        /// <returns></returns>
        public ActionResult Index(string webId, string webName)
        {
            var model = new NovelViewModel();
            model.WebId = webId;
            model.WebName = webName ?? "小说管理";

            return View(model);
        }

        // POST: Novel/Delete/5
        [HttpPost, ActionName("Delete")]
        public async Task<IActionResult> DeleteConfirmed(string id)
        {
            using var transaction = await _context.Database.BeginTransactionAsync();

            try
            {
                if (_context.Novels == null)
                {
                    return Problem("Entity set 'WisdomRecyclingContext.RecyclingSites' is null.");
                }
                var Novel = await _context.Novels.FindAsync(id);
                if (Novel != null)
                {
                    _context.Novels.Remove(Novel);
                }

                await _context.SaveChangesAsync();
                await transaction.CommitAsync(); // 事务提交
                return Json(new { success = true, message = "小说删除成功" });
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync(); // 事务回滚
                _logger.LogError($"{nameof(DeleteConfirmed)}：{ex}");
                return Json(new { success = false, message = ex.Message });
            }
        }

        /// <summary>
        /// 批量删除数据
        /// POST: Novel/BatchDelete/5,7
        /// </summary>
        /// <param name="id">数据编号集合</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> BatchDelete(string? id)
        {
            using var transaction = await _context.Database.BeginTransactionAsync();

            try
            {
                if (string.IsNullOrEmpty(id))
                {
                    return Json(new { success = false, Message = "要删除的小说数据主键集合为空！" });
                }
                var idarr = id.Trim().Split(',');
                foreach (var idd in idarr)
                {
                    var Novel = await _context.Novels.FindAsync(int.Parse(idd));
                    if (Novel != null) _context.Novels.Remove(Novel);
                }
                await _context.SaveChangesAsync();
                await transaction.CommitAsync(); // 事务提交
                return Json(new { success = true, message = "小说数据删除成功！" });
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync(); // 事务回滚
                _logger.LogError($"{nameof(BatchDelete)}：{ex}");
                return Json(new { success = false, message = ex.Message });
            }
        }

        private bool NovelExists(string? id)
        {
            return _context.Novels.Any(e => e.Id == id);
        }


        #region 小说列表数据视图

        /// <summary>
        /// 小说列表数据视图
        /// GET: Novel/TableList
        /// </summary>
        /// <param name="mid">菜单ID</param>
        /// <param name="mapname">菜单路径</param>
        /// <returns></returns>
        public IActionResult TableList(int? mid, string? mapname)
        {
            NovelDto dto = new();
            var model = _mapper.Map<NovelViewModel>(dto);
            return View(model);
        }

        #endregion 

        #region 小说分页数据查询

        /// <summary>
        /// 小说分页数据查询
        /// GET: Novel/PageList
        /// </summary>
        /// <param name="pageNumber">当前页码</param>
        /// <param name="pageSize">分页大小</param>
        /// <param name="title">检索关键词</param>
        /// <param name="webId">站点ID</param>
        /// <returns></returns>
        public JsonResult PageList(int? pageNumber, int? pageSize, string? title, string? startDate, string? endDate, string? webId)
        {
            try
            {
                #region 参数处理

                var urlDecode = HttpUtility.UrlDecode(title);
                if (urlDecode != null) title = title == null ? "" : urlDecode.Trim();

                string strQry = "";

                if (!string.IsNullOrEmpty(title))
                {
                    //strQry += string.Format(@" AND (n.Title LIKE '%{0}%' OR n.ABCDEF LIKE '%{0}%')", title);
                }
                if (!string.IsNullOrEmpty(webId))
                {
                    strQry += string.Format(@" AND (n.WebId = '{0}')", webId);
                }
                // 起止日期
                if (!string.IsNullOrEmpty(startDate) && !string.IsNullOrEmpty(endDate))
                {
                    strQry += string.Format(@" AND(unix_timestamp(n.`CreateTime`) between unix_timestamp('{0}') and unix_timestamp(DATE_ADD('{1}', INTERVAL 1 DAY)))", startDate, endDate);
                }
                if (!string.IsNullOrEmpty(startDate) && string.IsNullOrEmpty(endDate))
                {
                    strQry += string.Format(@" AND(unix_timestamp(n.`CreateTime`) > unix_timestamp('{0}'))", startDate, endDate);
                }
                if (string.IsNullOrEmpty(startDate) && !string.IsNullOrEmpty(endDate))
                {
                    strQry += string.Format(@" AND(unix_timestamp(n.`CreateTime`) < unix_timestamp(DATE_ADD('{1}', INTERVAL 1 DAY)))", startDate, endDate);
                }

                #endregion

                #region 分页及页码数据处理处理

                if (!pageNumber.HasValue) pageNumber = 1;
                if (!pageSize.HasValue) pageSize = 10;

                var skip = (pageNumber.Value - 1) * pageSize.Value;

                var min = (pageNumber - 1) * pageSize + 1;
                var max = pageNumber * pageSize;

                #endregion

                var strSql = string.Format(@"
	                ;WITH PageTb AS (
		                SELECT ROW_NUMBER() OVER (ORDER BY CreateTime) RowNumber
			                ,Id,WebId,Title,NovelUrl,Author,Status,ChapterChar,ChapterCount,CreateTime,UpdateTime
		                FROM dbo.[Novels] n WHERE (1 = 1) 
		                 {2} 
		                )
	                SELECT * 
	                FROM PageTb a
	                CROSS JOIN (SELECT MAX(RowNumber) AS RecordCount FROM PageTb) AS b 
	                WHERE (a.RowNumber BETWEEN {0} AND {1});
                 ", min, max, strQry);

                var list = Db.Ado.SqlQuery<NovelDto>(strSql);

                return Json(new { success = true, total = list?.Count > 0 ? list[0].RecordCount : 0, rows = list });
            }
            catch (Exception ex)
            {
                _logger.LogError($"{nameof(PageList)}：{ex}");
                return Json(new { success = false, total = 0, rows = new List<Hashtable>(), message = ex.Message });
            }
        }

        #endregion

        #region 小说数据保存

        /// <summary>
        /// 小说数据保存
        /// POST: Novel/Save
        /// </summary>
        /// <param name="Novel">小说</param>
        /// <returns></returns>
        public async Task<IActionResult> Save([FromBody] Novel Novel)
        {
            try
            {
                string flag;
                if (string.IsNullOrEmpty(Novel.Id) || !NovelExists(Novel.Id))
                {
                    flag = "添加";
                    Novel.Id = Guid.NewGuid().ToString().ToUpper();
                    Novel.CreateTime = DateTime.Now;
                    _context.Add(Novel);
                }
                else
                {
                    flag = "修改";
                    Novel.UpdateTime = DateTime.Now;
                    _context.Update(Novel);
                }

                await _context.SaveChangesAsync();

                return Json(new { success = true, message = $"小说数据{flag}成功!" });

            }
            catch (Exception ex)
            {
                _logger.LogError($"{nameof(Save)}：{ex}");
                return Json(new { success = false, message = ex.Message });
            }
        }

        #endregion


        /// <summary>
        /// 输出下载小说
        /// GET: Novel/Download/5,7
        /// </summary>
        /// <param name="id">小说ID</param>
        /// <returns></returns>
        public async Task<IActionResult> Download(string? id)
        {
            try
            {
                #region 参数检查

                if (string.IsNullOrEmpty(id))
                {
                    throw new Exception("小说ID为空");
                }

                var novel = await Db.Queryable<Novel>().InSingleAsync(id);

                if(novel == null)
                {
                    throw new Exception("小说数据为空");
                }

                #endregion

                var rootPath = _env.WebRootPath;
                var filePath = $"{rootPath}/novels/";
                FileHelper.PathCheck(filePath); // 检查目录
                var fileName = novel.Title;                
                var novelPath = $@"{filePath}{fileName}.txt";
                FileHelper.FileDelete(novelPath); // 删除文件

                //await Console.Out.WriteLineAsync(filePath);
                //await Console.Out.WriteLineAsync(novelPath);

                //throw new Exception("*********************");

                var strSql = string.Format(@"
                        SELECT a.*, c.[Contents]
                        FROM [dbo].[Chapters] a
                        INNER JOIN [dbo].[Contents] c ON c.ChapterId = a.Id
                        WHERE (a.NovelId = '{0}')
                        ORDER BY a.ChapterIdx
                        ;", id);

                List<ChapterDto> dtos = await Db.Ado.SqlQueryAsync<ChapterDto>(strSql);               

                var sw = System.IO.File.CreateText(novelPath); // 创建文本

                sw.WriteLine("");
                sw.WriteLine(novel.Title);
                sw.WriteLine("");
                sw.WriteLine($"作者：{novel.Author}");
                sw.WriteLine("");

                foreach (var chapter in dtos)
                {
                    if (chapter.WordCount <= 200) continue; // 短内容不输出

                    sw.WriteLine(string.IsNullOrEmpty(chapter.ChapterTitle) ? "第" + chapter.ChapterIdx + "章 标题缺失" : chapter.ChapterTitle);
                    sw.WriteLine("");
                    sw.WriteLine(chapter.Contents);
                    sw.WriteLine("");
                }

                sw.Close();

                return File(new FileStream(novelPath, FileMode.Open), "text/plain", novel.Title + ".txt");
            }
            catch (Exception ex)
            {
                _logger.LogError($"{nameof(Download)}：{ex}");
                return Json(new { success = false, message = ex.Message });
            }
        }

    }
}
